package com.shopping.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.shopping.mapper.UserMapper;
import com.shopping.model.UserInfo;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 处理认证逻辑的类
 * + 该类需要重写接口中的loadUserByUsername方法根据用户名获得用户对象
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private UserMapper userMapper;

    /**
     * 1.根据用户名获得用户信息
     * 2.将用户信息认证需要的数据封装到UserDetails的实现类对象中(UserInfo)
     * 3.将封装好的认证信息提交给SpringSecurity进行认证
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = userMapper.queryUserByUserName(username);
        //设置当前账户权限集合
        //判断用户名是否正确
        if (userInfo == null) {//用户不存在
            throw new UsernameNotFoundException("用户名不存在");
        }
        if (userInfo.getUser_status() == -1) {//用户被冻结
            
        }

        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        //为保护密码信息，将密码取出来后设为null
        String password = userInfo.getUser_password();
        userInfo.setUser_password(null);
        User user = new User(
                JSONObject.toJSONString(userInfo),//将用户对象转化为json串
                password,
                true,//账户是否启用
                true,//账户是否过期
                true,//凭证是否过期
                userInfo.getUser_status() == 0 ? true : false,//账户是否被锁定
                authorities//账户拥有权限集合
        );

        return user;
    }
}
